home *** CD-ROM | disk | FTP | other *** search
- #include "drawgraphics.h"
-
- /* Version 3.52c. Copyright (c) 1986-1993 by Joseph Felsenstein and
- Christopher A. Meacham. Additional code written by Hisashi Horino,
- Sean Lamont, Andrew Keefe, and Akiko Fuseki.
- Permission is granted to copy, distribute,
- and modify this program provided that (1) this copyright message is
- not removed and (2) no fee is charged for this program. */
-
- #define maxnch 30
- #define point '.'
- #define fontsize 3800
- #define pi 3.141592653
- #define epsilon 0.00001
- #define xstart 10
- #define ystart 35
- #define gap 0.5
- #define iterations 5
-
- #ifdef MAC
- #undef maxnodes
- #define maxnodes 250
- #endif
-
- typedef enum { fixed, radial, along} labelorient;
- FILE *treefile, *plotfile;
- char pltfilename[100];
- long ntips, nextnode, strpwide, strpdeep,
- strptop, strpbottom, payge, numlines;
- double xmargin, ymargin, topoflabels, rightoflabels, leftoflabels,
- bottomoflabels, ark, maxx, maxy, minx, miny, scale, xscale,
- yscale, xoffset, yoffset, charht, xnow, ynow, xunitspercm,
- yunitspercm, xsize, ysize, xcorner, ycorner,labelheight,
- labelrotation, treeangle, expand, bscale,enthusiasm;
- boolean canbeplotted, preview, previewing, dotmatrix,haslengths,
- uselengths, regular, didreroot, rotate, empty, rescaled,
- notfirst, improve;
- double textlength[maxnodes], firstlet[maxnodes];
- striptype stripe;
- plottertype plotter, oldplotter, previewer;
- growth grows;
- labelorient labeldirec;
- node *root, *where;
- node *nodep[maxnodes];
- fonttype font;
- enum { yes, no } penchange, oldpenchange;
- char ch;
- char fontname[64];
- long filesize;
- long strpdiv;
-
- openfile(fp,filename,mode,application,perm)
- FILE **fp;
- char *filename;
- char *mode;
- char *application;
- char *perm;
- {
- FILE *of;
- char file[100];
- strcpy(file,filename);
- while (1){
- of = fopen(file,mode);
- if (of)
- break;
- else {
- switch (*mode){
- case 'r':
- printf("%s: can't read %s\n",application,file);
- file[0]='\0';
- while (file[0] =='\0'){
- printf("Please enter a new filename>");
- gets(file);}
- break;
- case 'w':
- printf("%s: can't write %s\n",application,file);
- file[0] = '\0';
- while (file[0] =='\0'){
- printf("Please enter a new filename>");
- gets(file);}
- break;
- }
- }
- }
- *fp=of;
- if (perm != NULL)
- strcpy(perm,file);
- }
-
- void uppercase(ch)
- Char *ch;
- {
- /* make ch upper-case */
- *ch = (islower(*ch) ? toupper(*ch) : (*ch));
- } /* uppercase */
-
- /* Local variables for treeread: */
-
- void getch(c)
- Char *c;
- {
- /* get next nonblank character */
- do {*c = getc(treefile);
- } while ((*c == ' ')||(*c == '\n')||(*c == '\t'));
- } /* getch */
-
- void processlength(p)
- node *p;
- {
- long digit, ordzero;
- double valyew, divisor;
- boolean pointread, minusread;
-
- ordzero = '0';
- pointread = false;
- minusread = false;
- valyew = 0.0;
- divisor = 1.0;
- getch(&ch);
- digit = ch - ordzero;
- while (((unsigned long)digit <= 9) || (ch == '.') || (ch == '.')){
- if (ch == '.') pointread = true;
- else if (ch == '-') minusread = true;
- else {
- valyew = valyew * 10.0 + digit;
- if (pointread)
- divisor *= 10.0;
- }
- getch(&ch);
- digit = ch - ordzero;
- }
- if (!minusread)
- p->oldlen = valyew / divisor;
- else
- p->oldlen = 0.0;
- /* processlength */
- }
-
- void addelement(p, q)
- node **p, *q;
- {
- /* read in and add next part of tree, it will be node p
- and will be hooked to pointer q */
- node *pp;
- long n,indx;
- boolean notlast;
-
- nextnode++;
- *p = (node *)Malloc((long)sizeof(node));
- nodep[nextnode - 1] = *p;
- indx = nextnode;
- (*p)->index = indx;
- if (ch == '(') {
- (*p)->tip = false;
- pp = *p;
- notlast = true;
- while (notlast) {
- pp->next = (node *)Malloc((long)sizeof(node));
- pp->next->tip = false;
- nextnode++;
- nodep[nextnode - 1] = pp->next;
- pp->next->index = indx;
- pp = pp->next;
- getch(&ch);
- addelement(&pp->back, pp);
- if (ch == ')') {
- notlast = false;
- do {
- getch(&ch);
- } while (ch != ':' && ch != ',' && ch != ')' && ch != '[' &&
- ch != ';');
- }
- }
- pp->next = *p;
- } else {
- (*p)->tip = true;
- ntips++;
- n = 1;
- do {
- if (!ebcdic && (ch & 255) == 255)
- ch = '\'';
- if (!ebcdic && (ch & 255) > 175)
- ch -= 48;
- if (!ebcdic && (ch & (~127)) != 0)
- ch -= 64;
- if (ch == '_')
- ch = ' ';
- if (n < maxnch)
- (*p)->nayme[n - 1] = ch;
- if (eoln(treefile)) {
- fscanf(treefile, "%*[^\n]");
- (void)getc(treefile);
- }
- ch = getc(treefile);
- if (ch == '\n')
- ch = ' ';
- n++;
- } while (ch != ':' && ch != ',' && ch != ')');
- if (n > maxnch)
- n = maxnch + 1;
- (*p)->naymlength = n - 1;
- }
- if (ch == ':')
- processlength(*p);
- else
- haslengths = (haslengths && q == NULL);
- (*p)->back = q;
- if (haslengths && q != NULL)
- (*p)->back->oldlen = (*p)->oldlen;
- (*p)->r = 0.0;
- (*p)->theta = 0.0;
- } /* addelement */
-
- void treeread()
- {
- /* read a tree from the treefile and set up nodes and pointers */
- haslengths = true;
- ntips = 0;
- nextnode = 0;
- getch(&ch);
- addelement(&root, NULL);
- root->oldlen = 0.0;
- fscanf(treefile, "%*[^\n]");
- (void)getc(treefile);
- uselengths = haslengths;
- where = root;
- rotate = true;
- } /* treeread */
-
- void initialparms()
- {
- /* initialize parameters */
-
- getplotter();
- plotrparms();
- xmargin = 0.08 * xsize;
- ymargin = 0.08 * ysize;
- xscale = xunitspercm;
- yscale = yunitspercm;
- grows = vertical;
- treeangle = pi / 2.0;
- ark = 2 * pi;
- improve = true;
- regular = false;
- rescaled = true;
- bscale = 1.0;
- labeldirec = fixed;
- labelrotation = 0.0;
- charht = 0.3333;
- numlines = dotmatrix ? ((long)floor(yunitspercm * ysize + 0.5) / strpdeep):1;
- enthusiasm = 1.0/(double)ntips;
- } /* initialparms */
-
-
- long showparms()
- {
- long i;
- long numtochange;
- Char ch,input[64];
- double treea;
-
- putchar('\n');
- if (previewer == tek)
- printf("%c\f", escape);
- else {
- for (i = 1; i <= 24; i++)
- putchar('\n');
- }
- printf("Here are the settings: \n\n");
- printf(" (1) Use branch lengths: ");
- if (haslengths)
- printf("%s\n",uselengths ? "Yes" : "No");
- else
- printf("(no branch lengths available)\n");
- printf(" (2) Angle of labels:");
- if (labeldirec == fixed) {
- printf(" Fixed angle of");
- if (labelrotation >= 10.0)
- printf("%6.1f", labelrotation);
- else if (labelrotation <= -10.0)
- printf("%7.1f", labelrotation);
- else if (labelrotation < 0.0)
- printf("%6.1f", labelrotation);
- else
- printf("%5.1f", labelrotation);
- printf(" degrees\n");
- } else if (labeldirec == radial)
- printf(" Radial\n");
- else
- printf(" Along branches\n");
- printf(" (3) Rotation of tree:");
- treea = treeangle * 180 / pi;
- if (treea >= 100.0)
- printf("%7.1f\n", treea);
- else if (treea >= 10.0)
- printf("%6.1f\n", treea);
- else if (treea <= -100.0)
- printf("%8.1f\n", treea);
- else if (treea <= -10.0)
- printf("%7.1f\n", treea);
- else if (treea < 0.0)
- printf("%6.1f\n", treea);
- else
- printf("%5.1f\n", treea);
- printf(" (4) Angle of arc for tree:");
- treea = 180 * ark / pi;
- if (treea >= 100.0)
- printf("%7.1f\n", treea);
- else if (treea >= 10.0)
- printf("%6.1f\n", treea);
- else if (treea <= -100.0)
- printf("%8.1f\n", treea);
- else if (treea <= -10.0)
- printf("%7.1f\n", treea);
- else if (treea < 0.0)
- printf("%6.1f\n", treea);
- else
- printf("%5.1f\n", treea);
- printf(" (5) Iterate to improve tree: %s\n",
- (improve ? "Yes" : "No"));
- printf(" (6) Scale of branch length:");
- if (rescaled)
- printf(" Automatically rescaled\n");
- else
- printf(" Fixed:%6.2f cm per unit branch length\n", bscale);
- didreroot = false;
- printf(" (7) Horizontal margins:%6.2f cm\n", xmargin);
- printf(" (7) Vertical margins:%6.2f cm\n", ymargin);
- printf(" (8) Relative character height:%8.4f\n", charht);
- if (!improve)
- printf(" (9) Regularize the angles: %s\n",(regular ? "Yes" : "No"));
- else
- printf(" (9) Enthusiasm constant:%9.5f\n",enthusiasm);
- if (plotter == lw)
- printf(" (10) Font : %s\n",fontname);
-
- printf("\n\n Do you want to accept these? (Yes or No)\n");
- for (;;) {
- printf(" Type Y or N or the number (1-%2ld) of the one to change: \n",
- (plotter == lw) ? 10L : 9L);
- gets(input);
- uppercase(&input[0]);
- ch=input[0];
- numtochange = atoi(input);
- if ((ch == 'Y' || ch == 'N') || (numtochange >= 1 && numtochange <=
- ((plotter == lw) ? 10 : 9)))
- break;
- }
- return (ch == 'Y') ? -1 : numtochange;
- } /* showparms */
-
- void rerootit(p)
- node *p;
- {
- node *q;
-
- q = root;
- while (q->next != root)
- q = q->next;
- q->next = root->next;
- q = p;
- while (q->next != p)
- q = q->next;
- root->next = p;
- q->next = root;
- } /* rerootit */
-
- void reroot()
- {
- /* reroot the tree, traversing tree */
- where = root->next;
- if (!rotate)
- rotate = where->back->tip;
- if (rotate) {
- where = where->next;
- rotate = false;
- } else {
- where = where->back;
- rotate = true;
- }
- rerootit(where);
- } /* reroot */
-
-
- void getparms(numtochange)
- long numtochange;
- {
- /* get from user the relevant parameters for the plotter and diagram */
- Char ch;
- boolean ok;
-
- if (numtochange == 0) {
- do {
- printf(" Type the number of one that you want to change (1-%2ld):\n",
- (plotter == lw) ? 10L : 9L);
- scanf("%ld%*[^\n]", &numtochange);
- (void)getchar();
- } while (numtochange < 1 || numtochange > ((plotter == lw) ? 10 : 9));
- }
- switch (numtochange) {
-
- case 1:
- if (haslengths)
- uselengths = !uselengths;
- else {
- printf("Cannot use lengths since not all of them exist\n");
- uselengths = false;
- }
- break;
-
- case 2:
- printf("\nDo you want labels to be Fixed angle, Radial,");
- printf(" or Along branches?\n");
- do {
- printf(" Type F, R, or A\n");
- scanf("%c%*[^\n]", &ch);
- (void)getchar();
- if (ch == '\n')
- ch = ' ';
- uppercase(&ch);
- } while (ch != 'F' && ch != 'R' && ch != 'A');
- switch (ch) {
-
- case 'A':
- labeldirec = along;
- break;
-
- case 'F':
- labeldirec = fixed;
- break;
-
- case 'R':
- labeldirec = radial;
- break;
- }
- if (labeldirec == fixed) {
- printf("Are the labels to be plotted vertically (90),\n");
- printf(" horizontally (0), or downwards (-90) ?\n");
- do {
- printf(" Choose an angle in degrees from 90 to -90: \n");
- scanf("%lf%*[^\n]", &labelrotation);
- (void)getchar();
- } while ((labelrotation < -90.0 || labelrotation > 90.0) &&
- labelrotation != -99.0);
- }
- break;
-
- case 3:
- printf("\n At what angle is the tree to be plotted?\n");
- do {
- printf(" Choose an angle in degrees from 360 to -360: \n");
- scanf("%lf%*[^\n]", &treeangle);
- (void)getchar();
- uppercase(&ch);
- } while (treeangle < -360.0 && treeangle > 360.0);
- treeangle = treeangle * pi / 180;
- break;
-
- case 4:
- printf(" How many degrees (up to 360) of arc\n");
- printf(" should the tree occupy? (Currently it is %5.1f)\n",
- 180 * ark / pi);
- do {
- printf("Enter a number of degrees from 0 up to 360)\n");
- scanf("%lf%*[^\n]", &ark);
- (void)getchar();
- } while (ark <= 0.0 || ark > 360.0);
- ark = ark * pi / 180;
- break;
-
- case 5:
- improve = !improve;
- break;
-
- case 6:
- rescaled = !rescaled;
- if (!rescaled) {
- printf("Centimeters per unit branch length?\n");
- scanf("%lf%*[^\n]", &bscale);
- (void)getchar();
- }
- break;
-
- case 7:
- printf("\nThe tree will be drawn to fit in a rectangle which has \n");
- printf(" margins in the horizontal and vertical directions of:\n");
- printf("%6.2f cm (horizontal margin) and%6.2f cm (vertical margin)\n\n",
- xmargin, ymargin);
- do {
- printf(" New value (in cm) of horizontal margin?\n");
- scanf("%lf%*[^\n]", &xmargin);
- (void)getchar();
- ok = ((unsigned)xmargin < xsize / 2.0);
- if (!ok)
- printf(" Impossible value. Please retype it.\n");
- } while (!ok);
- do {
- printf(" New value (in cm) of vertical margin?\n");
- scanf("%lf%*[^\n]", &ymargin);
- (void)getchar();
- ok = ((unsigned)ymargin < ysize / 2.0);
- if (!ok)
- printf(" Impossible value. Please retype it.\n");
- } while (!ok);
- break;
-
- case 8:
- printf("New value of character height?\n");
- scanf("%lf%*[^\n]", &charht);
- (void)getchar();
- break;
- case 9:
- if (improve) {
- do {
- printf("Enthusiasm constant? (must be between 0 and 1)\n");
- scanf("%lf%*[^\n]", &enthusiasm);
- getchar();
- } while (enthusiasm <= 0.0 || enthusiasm > 1.0);}
- else
- regular = !regular;
- break;
- case 10:
- printf("Enter font name or \"Hershey\" for default font\n");
- gets(fontname);
- break;
- }
- } /* getparms */
-
-
- Local void getwidth(p)
- node *p;
- {
- /* get width and depth beyond each node */
- double nw, nd;
- node *pp, *qq;
-
- nd = 0.0;
- if (p->tip)
- nw = 1.0;
- else {
- nw = 0.0;
- qq = p;
- pp = p->next;
- do {
- getwidth(pp->back);
- nw += pp->back->width;
- if (pp->back->depth > nd)
- nd = pp->back->depth;
- pp = pp->next;
- } while (pp != qq);
- }
- p->depth = nd + p->length;
- p->width = nw;
- } /* getwidth */
-
- void plrtrans(p, theta, lower, upper)
- node *p;
- double theta, lower, upper;
- {
- /* polar coordinates of a node relative to start */
- long num;
- double nn, pr, ptheta, angle, angle2, subangle, len;
- node *pp, *qq;
-
- nn = p->width;
- angle = theta;
- subangle = (upper - lower) / nn;
- qq = p;
- pp = p->next;
- if (p->tip)
- return;
- angle = upper;
- do {
- angle -= pp->back->width / 2.0 * subangle;
- pr = p->r;
- ptheta = p->theta;
- if (regular) {
- num = 1;
- while (num * subangle < 2 * pi)
- num *= 2;
- if (angle >= 0.0)
- angle2 = 2 * pi / num * (long)(num * angle / (2 * pi) + 0.5);
- else
- angle2 = 2 * pi / num * (long)(num * angle / (2 * pi) - 0.5);
- } else
- angle2 = angle;
- if (uselengths)
- len = pp->back->oldlen;
- else
- len = 1.0;
- pp->back->r = sqrt(len * len + pr * pr + 2 * len * pr * cos(angle2 - ptheta));
- if (fabs(pr * cos(ptheta) + len * cos(angle2)) > epsilon)
- pp->back->theta = atan((pr * sin(ptheta) + len * sin(angle2)) /
- (pr * cos(ptheta) + len * cos(angle2)));
- else if (pr * sin(ptheta) + len * sin(angle2) >= 0.0)
- pp->back->theta = pi / 2;
- else
- pp->back->theta = 1.5 * pi;
- if (pr * cos(ptheta) + len * cos(angle2) < -epsilon)
- pp->back->theta += pi;
- if (!pp->back->tip)
- plrtrans(pp->back, pp->back->theta,
- angle - pp->back->width * subangle / 2.0,
- angle + pp->back->width * subangle / 2.0);
- else
- pp->back->oldtheta = angle2;
- angle -= pp->back->width / 2.0 * subangle;
- pp = pp->next;
- } while (pp != qq);
- } /* plrtrans */
-
- void coordtrav(p, xx, yy)
- node *p;
- double *xx, *yy;
- {
- /* compute x and y coordinates */
- long i;
- node *pp;
-
- if (!p->tip) {
- pp = p->next;
- while (pp != p) {
- coordtrav(pp->back, xx,yy);
- pp = pp->next;
- }
- }
- if (p->tip) {
- i = 1;
- while (nodep[i - 1] != p)
- i++;
- textlength[i - 1] = (double)lengthtext(p->nayme, p->naymlength, font);
- }
- (*xx) = p->r * cos(p->theta);
- (*yy) = p->r * sin(p->theta);
- if ((*xx) > maxx)
- maxx = (*xx);
- if ((*xx) < minx)
- minx = (*xx);
- if ((*yy) > maxy)
- maxy = (*yy);
- if ((*yy) < miny)
- miny = (*yy);
- p->xcoord = (*xx);
- p->ycoord = (*yy);
- } /* coordtrav */
-
-
- double angleof(x, y)
- double x, y;
- {
- /* compute the angle of a vector */
- double theta;
-
- if (fabs(x) > epsilon)
- theta = atan(y / x);
- else if (y >= 0.0)
- theta = pi / 2;
- else
- theta = 1.5 * pi;
- if (x < -epsilon)
- theta = pi + theta;
- if (theta > 2 * pi)
- theta -= 2 * pi;
- return theta;
- } /* angleof */
-
- void polartrav(p,xx,yy,leftx,lefty,rightx,righty)
- node *p;
- double *xx,*yy,*leftx,*lefty,*rightx,*righty;
- {
- /* go through subtree getting left and right vectors */
- double x, y;
- boolean lookatit;
- node *pp;
-
- lookatit = true;
- if (!p->tip)
- lookatit = (p->next->next->next != p || p->index != root->index);
- if (lookatit) {
- x = nodep[p->index - 1]->xcoord;
- y = nodep[p->index - 1]->ycoord;
- if ((y - (*yy)) * (*rightx) - (x - (*xx)) * (*righty) < 0.0) {
- (*rightx) = x - (*xx);
- (*righty) = y - (*yy);
- }
- if ((y - (*yy)) * (*leftx) - (x - (*xx)) * (*lefty) > 0.0 &&
- !(notfirst && fabs((*rightx) - x + (*xx)) +
- fabs((*righty) - y + (*yy)) < epsilon)) {
- (*leftx) = x - (*xx);
- (*lefty) = y - (*yy);
- notfirst = true;
- }
- }
- if (p->tip)
- return;
- pp = p->next;
- while (pp != p) {
- if (pp != root)
- polartrav(pp->back,xx,yy,leftx,lefty,rightx,righty);
- pp = pp->next;
- }
- } /* polartrav */
-
- void tilttrav(q,xx,yy,sinphi,cosphi)
- node *q;
- double *xx,*yy,*sinphi,*cosphi;
- {
- /* traverse to move successive nodes */
- double x, y;
- node *pp;
-
- pp = nodep[q->index - 1];
- x = pp->xcoord;
- y = pp->ycoord;
- pp->xcoord = (*xx) + (x - (*xx)) * (*cosphi) + (y - (*yy)) * (*sinphi);
- pp->ycoord = (*yy) + ((*xx) - x) * (*sinphi) + (y - (*yy)) * (*cosphi);
- if (q->tip)
- return;
- pp = q->next;
- while (pp != q) {
- if (pp != root)
- tilttrav(pp->back,xx,yy,sinphi,cosphi);
- pp = pp->next;
- }
- } /* tilttrav */
-
- void polarize(p,xx,yy)
- node *p;
- double *xx,*yy;
- {
- double TEMP, TEMP1;
-
- if (fabs(p->xcoord - (*xx)) > epsilon)
- p->oldtheta = atan((p->ycoord - (*yy)) / (p->xcoord - (*xx)));
- else if (p->ycoord - (*yy) >= 0.0)
- p->oldtheta = pi / 2;
- else
- p->oldtheta = 1.5 * pi;
- if (p->xcoord - (*xx) < -epsilon)
- p->oldtheta += pi;
- if (fabs(p->xcoord - root->xcoord) > epsilon)
- p->theta = atan((p->ycoord - root->ycoord) / (p->xcoord - root->xcoord));
- else if (p->ycoord - root->ycoord >= 0.0)
- p->theta = pi / 2;
- else
- p->theta = 1.5 * pi;
- if (p->xcoord - root->xcoord < -epsilon)
- p->theta += pi;
- TEMP = p->xcoord - root->xcoord;
- TEMP1 = p->ycoord - root->ycoord;
- p->r = sqrt(TEMP * TEMP + TEMP1 * TEMP1);
- } /* polarize */
-
- void improvtrav(p)
- node *p;
- {
- /* traverse tree trying different tiltings at each node */
- double xx, yy, leftx, lefty, rightx, righty, cosphi, sinphi;
- long n;
- double usedangle, langle, rangle, freeangle, meanangle, sumrot;
- node *pp, *qq;
-
- if (p->tip)
- return;
- xx = p->xcoord;
- yy = p->ycoord;
- if (p != root) {
- n = 0;
- usedangle = 0.0;
- pp = p->next;
- do {
- leftx = pp->back->xcoord - xx;
- lefty = pp->back->ycoord - yy;
- rightx = leftx;
- righty = lefty;
- notfirst = false;
- if (!pp->back->tip)
- polartrav(pp->back, &xx,&yy,&leftx,&lefty,&rightx,&righty);
- n++;
- langle = angleof(leftx, lefty);
- rangle = angleof(rightx, righty);
- if (rangle > langle)
- langle += 2 * pi;
- pp->lefttheta = langle;
- pp->righttheta = rangle;
- usedangle += langle - rangle;
- pp = pp->next;
- } while (pp != p->next);
- freeangle = 2 * pi - usedangle;
- meanangle = freeangle / n;
- sumrot = 0.0;
- qq = p;
- pp = p->next;
- while (pp != p) {
- langle = qq->righttheta;
- rangle = pp->lefttheta;
- if (rangle > langle)
- langle += 2 * pi;
- sumrot += enthusiasm * (meanangle - langle + rangle);
- cosphi = cos(sumrot);
- sinphi = sin(sumrot);
- if (pp != root)
- tilttrav(pp->back, &xx,&yy,&sinphi,&cosphi);
- qq = pp;
- pp = pp->next;
- }
- }
- pp = p->next;
- while (pp != p) {
- if (pp != root)
- polarize(pp->back, &xx,&yy);
- pp = pp->next;
- }
- pp = p->next;
- while (pp != p) {
- if (pp != root)
- improvtrav(pp->back);
- pp = pp->next;
- }
- } /* improvtrav */
-
- void coordimprov(xx,yy)
- double *xx,*yy;
- {
- /* use angles calculation to improve node coordinate placement */
- long i;
- for (i = 1; i <= iterations; i++)
- improvtrav(root);
- } /* coordimprov */
-
-
- void calculate()
- {
- /* compute coordinates for tree */
- double xx, yy;
- long i;
- double nttot, fontheight, labangle, top, bot, rig, lef;
-
- for (i = 0; i < nextnode; i++)
- nodep[i]->width = 1.0;
- for (i = 0; i < nextnode; i++)
- nodep[i]->xcoord = 0.0;
- for (i = 0; i < nextnode; i++)
- nodep[i]->ycoord = 0.0;
- if (!uselengths) {
- for (i = 0; i < nextnode; i++)
- nodep[i]->length = 1.0;
- } else {
- for (i = 0; i < nextnode; i++)
- nodep[i]->length = nodep[i]->oldlen;
- }
- getwidth(root);
- nttot = root->width;
- for (i = 0; i < nextnode; i++)
- nodep[i]->width = nodep[i]->width * ntips / nttot;
- plrtrans(root, treeangle, treeangle - ark / 2.0, treeangle + ark / 2.0);
- maxx = 0.0;
- minx = 0.0;
- maxy = 0.0;
- miny = 0.0;
- coordtrav(root, &xx,&yy);
- if (improve) {
- coordimprov(&xx,&yy);
- coordtrav(root, &xx,&yy);
- }
- fontheight = font[2];
- if (labeldirec == fixed)
- labangle = pi * labelrotation / 180.0;
- for (i = 0; i < nextnode; i++) {
- if (nodep[i]->tip)
- textlength[i] /= fontheight;
- }
- if (ntips > 1)
- labelheight = charht * (maxx - minx) / (ntips - 1);
- else
- labelheight = charht * (maxx - minx);
- topoflabels = 0.0;
- bottomoflabels = 0.0;
- rightoflabels = 0.0;
- leftoflabels = 0.0;
- for (i = 0; i < nextnode; i++) {
- if (nodep[i]->tip) {
- if (labeldirec == radial)
- labangle = nodep[i]->theta;
- else if (labeldirec == along)
- labangle = nodep[i]->oldtheta;
- if (cos(labangle) < 0.0 && labeldirec != fixed)
- labangle -= pi;
- firstlet[i] = (double)lengthtext(nodep[i]->nayme,1L,font)/ fontheight;
- top = (nodep[i]->ycoord - maxy) / labelheight + sin(nodep[i]->oldtheta);
- rig = (nodep[i]->xcoord - maxx) / labelheight + cos(nodep[i]->oldtheta);
- bot = (miny - nodep[i]->ycoord) / labelheight - sin(nodep[i]->oldtheta);
- lef = (minx - nodep[i]->xcoord) / labelheight - cos(nodep[i]->oldtheta);
- if (cos(labangle) * cos(nodep[i]->oldtheta) +
- sin(labangle) * sin(nodep[i]->oldtheta) > 0.0) {
- if (sin(labangle) > 0.0)
- top += sin(labangle) * textlength[i];
- top += sin(labangle - 1.25 * pi) * gap * firstlet[i];
- if (sin(labangle) < 0.0)
- bot -= sin(labangle) * textlength[i];
- bot -= sin(labangle - 0.75 * pi) * gap * firstlet[i];
- if (sin(labangle) > 0.0)
- rig += cos(labangle - 0.75 * pi) * gap * firstlet[i];
- else
- rig += cos(labangle - 1.25 * pi) * gap * firstlet[i];
- rig += cos(labangle) * textlength[i];
- if (sin(labangle) > 0.0)
- lef -= cos(labangle - 1.25 * pi) * gap * firstlet[i];
- else
- lef -= cos(labangle - 0.75 * pi) * gap * firstlet[i];
- } else {
- if (sin(labangle) < 0.0)
- top -= sin(labangle) * textlength[i];
- top += sin(labangle + 0.25 * pi) * gap * firstlet[i];
- if (sin(labangle) > 0.0)
- bot += sin(labangle) * textlength[i];
- bot -= sin(labangle - 0.25 * pi) * gap * firstlet[i];
- if (sin(labangle) > 0.0)
- rig += cos(labangle - 0.25 * pi) * gap * firstlet[i];
- else
- rig += cos(labangle + 0.25 * pi) * gap * firstlet[i];
- if (sin(labangle) < 0.0)
- rig += cos(labangle) * textlength[i];
- if (sin(labangle) > 0.0)
- lef -= cos(labangle + 0.25 * pi) * gap * firstlet[i];
- else
- lef -= cos(labangle - 0.25 * pi) * gap * firstlet[i];
- lef += cos(labangle) * textlength[i];
- }
- if (top > topoflabels)
- topoflabels = top;
- if (bot > bottomoflabels)
- bottomoflabels = bot;
- if (rig > rightoflabels)
- rightoflabels = rig;
- if (lef > leftoflabels)
- leftoflabels = lef;
- }
- }
- topoflabels *= labelheight;
- bottomoflabels *= labelheight;
- leftoflabels *= labelheight;
- rightoflabels *= labelheight;
- } /* calculate */
-
-
- void rescale()
- {
- /* compute coordinates of tree for plot or preview device */
- long i;
- double treeheight, treewidth, extrax, extray, temp;
-
- treeheight = maxy - miny + topoflabels + bottomoflabels;
- treewidth = maxx - minx + rightoflabels + leftoflabels;
- if (grows == vertical) {
- if (!rescaled)
- expand = bscale;
- else {
- expand = (xsize - 2 * xmargin) / treewidth;
- if ((ysize - 2 * ymargin) / treeheight < expand)
- expand = (ysize - 2 * ymargin) / treeheight;
- }
- extrax = (xsize - 2 * xmargin - treewidth * expand) / 2.0;
- extray = (ysize - 2 * ymargin - treeheight * expand) / 2.0;
- } else {
- if (!rescaled)
- expand = bscale;
- else {
- expand = (ysize - 2 * ymargin) / treewidth;
- if ((xsize - 2 * xmargin) / treeheight < expand)
- expand = (xsize - 2 * xmargin) / treeheight;
- }
- extrax = (xsize - 2 * xmargin - treeheight * expand) / 2.0;
- extray = (ysize - 2 * ymargin - treewidth * expand) / 2.0;
- }
- for (i = 0; i < (nextnode); i++) {
- nodep[i]->xcoord = expand * (nodep[i]->xcoord - minx + leftoflabels);
- nodep[i]->ycoord = expand * (nodep[i]->ycoord - miny + bottomoflabels);
- if (grows == horizontal) {
- temp = nodep[i]->ycoord;
- nodep[i]->ycoord = expand * treewidth - nodep[i]->xcoord;
- nodep[i]->xcoord = temp;
- }
- nodep[i]->xcoord += xmargin + extrax;
- nodep[i]->ycoord += ymargin + extray;
- }
- } /* rescale */
-
- void plottree(p, q)
- node *p, *q;
- {
- /* plot part or all of tree on the plotting device */
- double x1, y1, x2, y2;
- node *pp;
-
- x2 = xscale * (xoffset + p->xcoord);
- y2 = yscale * (yoffset + p->ycoord);
- if (p != root) {
- x1 = xscale * (xoffset + q->xcoord);
- y1 = yscale * (yoffset + q->ycoord);
- plot(penup, x1, y1);
- plot(pendown, x2, y2);
- }
- if (p->tip)
- return;
- pp = p->next;
- while (pp != p) {
- plottree(pp->back, p);
- pp = pp->next;
- }
- } /* plottree */
-
-
- void plotlabels(fontname)
- char *fontname;
- {
- long i;
- double compr, dx, dy, labangle;
- boolean left, right;
- node *lp;
-
- compr = xunitspercm / yunitspercm;
- if (penchange == yes)
- changepen(labelpen);
- for (i = 0; i < (nextnode); i++) {
- if (nodep[i]->tip) {
- lp = nodep[i];
- labangle = labelrotation * pi / 180.0;
- if (labeldirec == radial)
- labangle = nodep[i]->theta;
- else if (labeldirec == along)
- labangle = nodep[i]->oldtheta;
- if (cos(labangle) < 0.0)
- labangle -= pi;
- right = (cos(labangle) * cos(nodep[i]->oldtheta) +
- sin(labangle) * sin(nodep[i]->oldtheta) > 0.0);
- left = !right;
- dx = labelheight * expand * cos(nodep[i]->oldtheta);
- dy = labelheight * expand * sin(nodep[i]->oldtheta);
- if (right) {
- dx += labelheight * expand * 0.5 * firstlet[i] * cos(labangle - 0.75 * pi);
- dy += labelheight * expand * 0.5 * firstlet[i] * sin(labangle - 0.75 * pi);
- }
- if (left) {
- dx += labelheight * expand * 0.5 * firstlet[i] * cos(labangle - 0.25 * pi);
- dy += labelheight * expand * 0.5 * firstlet[i] * sin(labangle - 0.25 * pi);
- dx -= textlength[i] * labelheight * expand * cos(labangle);
- dy -= textlength[i] * labelheight * expand * sin(labangle);
- }
-
- plottext(lp->nayme, lp->naymlength,
- labelheight * expand * xscale / compr, compr,
- xscale * (lp->xcoord + dx + xoffset),
- yscale * (lp->ycoord + dy + yoffset), -180 * labangle / pi,
- font,fontname);
- }
- }
- if (penchange == yes)
- changepen(treepen);
- } /* plotlabels */
-
-
-
- #ifdef CHILDAPP
- void RealMain(int argc, char** argv)
- #else
- main(argc, argv)
- int argc;
- Char *argv[];
- #endif
-
- {
- long i,n,stripedepth;
- char filename1[100];
- #if defined(MAC) || defined(__MWERKS__)
- OSErr retcode;
- FInfo fndrinfo;
- #ifdef MAC
- macsetup("Drawtree","Preview");
- #endif
- #endif
- #ifdef TURBOC
- if ((registerbgidriver(EGAVGA_driver) <0) ||
- (registerbgidriver(Herc_driver) <0) ||
- (registerbgidriver(CGA_driver) <0)){
- fprintf(stderr,"Graphics error: %s ",grapherrormsg(graphresult()));
- exit(-1);}
- #endif
- strcpy(fontname,"Hershey");
-
- openfile(&plotfile,PLOTFILE,"w",argv[0],pltfilename);
- openfile(&treefile,TREEFILE,"r",argv[0],NULL);
-
- printf("DRAWTREE from PHYLIP version %s\n",VERSION);
- printf("Reading tree ... \n");
- treeread();
- printf("Tree has been read.\n");
- printf("Loading the font ... \n");
- loadfont(font,argv[0]);
- printf("Font loaded.\n");
- previewing = false;
- initialparms();
-
- canbeplotted = false;
- while (!canbeplotted) {
- do {
- n=showparms();
- if ( n != -1)
- getparms(n);
- } while (n != -1);
- calculate();
- rescale();
- canbeplotted = true;
- if (preview)
- canbeplotted=plotpreview(fontname,&xoffset,&yoffset,&scale,ntips,root);
- }
- if (dotmatrix) {
- stripedepth = allocstripe(stripe,(strpwide/8),
- ((long)(yunitspercm * ysize)));
- strpdeep = stripedepth;
- strpdiv = stripedepth;
- }
- previewing = false;
- initplotter(ntips,fontname);
- numlines = dotmatrix ? ((long)floor(yunitspercm * ysize + 0.5)/strpdeep):1; if (plotter != ibmpc)
- printf("Writing plot file ...\n");
- drawit(fontname,&xoffset,&yoffset,numlines,root);
- finishplotter();
- printf("Finished.\n");
- FClose(treefile);
- FClose(plotfile);
- printf("End of run.\n");
-
- #ifdef MAC
- if (plotter == pict){
- strcpy(filename1,pltfilename);
- retcode=GetFInfo(CtoPstr(filename1),0,&fndrinfo);
- fndrinfo.fdType='PICT';
- fndrinfo.fdCreator='MDRW';
- strcpy(filename1,pltfilename);
- retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
- if (plotter == lw){
- retcode=GetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);
- fndrinfo.fdType='TEXT';
- retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
- #endif
- #if defined(__MWERKS__)
- if (plotter == pict){
- strcpy(filename1,pltfilename);
- retcode= getfinfo( pltfilename,0,&fndrinfo);
- fndrinfo.fdType='PICT';
- fndrinfo.fdCreator='MDRW';
- retcode=setfinfo( pltfilename,0,&fndrinfo);
- }
- if (plotter == lw){
- retcode=getfinfo( pltfilename,0,&fndrinfo);
- fndrinfo.fdType='TEXT';
- retcode=setfinfo( pltfilename,0,&fndrinfo);
- }
- #endif
- exit(0);
- }
-
- int eof(f)
- FILE *f;
- {
- register long ch;
-
- if (feof(f))
- return 1;
- if (f == stdin)
- return 0;
- ch = getc(f);
- if (ch == EOF)
- return 1;
- ungetc(ch, f);
- return 0;
- }
-
-
- int eoln(f)
- FILE *f;
- {
- register long ch;
-
- ch = getc(f);
- if (ch == EOF)
- return 1;
- ungetc(ch, f);
- return (ch == '\n');
- }
-
-
- void memerror()
- {
- printf("Error allocating memory\n");
- exit(-1);
- }
-
- MALLOCRETURN *mymalloc(x)
- long x;
- {
- MALLOCRETURN *mem;
- mem = (MALLOCRETURN *)malloc(x);
- if (!mem)
- memerror();
- else
- return (MALLOCRETURN *)mem;
- }
-